/*
 * Copyright (c) 2016 moondev.cn
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package cn.moondev.moonlog.example.moonlog.monitor.handler.impl;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;

import cn.moondev.moonlog.example.moonlog.monitor.dao.BizMonitorDao;
import cn.moondev.moonlog.example.moonlog.monitor.entity.BizMonitor;
import cn.moondev.moonlog.example.moonlog.monitor.handler.MonitorMsgHandler;
import cn.moondev.moonlog.example.moonlog.monitor.utils.TableBuilder;
import org.joda.time.DateTime;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONException;
import com.google.common.base.CharMatcher;
import com.google.common.base.Splitter;

/**
 * 处理积分系统业务日志，用于监控方法执行时间
 * @date 2016年1月4日
 * @author chensc
 */
@Component
public class CreditBizMonitorHandler implements MonitorMsgHandler {
	
	private static final Logger log = LoggerFactory.getLogger(CreditBizMonitorHandler.class);
	
	@Autowired
	private BizMonitorDao dao;
	
    public void handle(List<String> msgList) {
    	List<BizMonitor> bizList = msgList2BizList(msgList);
    	if(bizList.size() == 0) {
    		return;
    	}
    	try {
    		dao.save(bizList, TableBuilder.buildBizMonitorTableName(new DateTime()));
    	}catch(Exception e) {
    		log.error("处理SQL日志出现异常",e);
    	}
    }
    
    /**
     * 日志列表转bizMonitor列表
     * @param msgList
     * @return
     */
    private List<BizMonitor> msgList2BizList(List<String> msgList) {
    	List<BizMonitor> bizs = new ArrayList<BizMonitor>();
    	for(String msg : msgList) {
    		BizMonitor biz = msg2biz(msg);
    		if(biz != null) {
    			bizs.add(biz);
    		}
    	}
    	return bizs;
    }

    /**
     * 单条日志转单个bizMonitor
     * @param msg
     * @return
     */
    @SuppressWarnings("unchecked")
	private BizMonitor msg2biz(String msg) {
    	BizMonitor bizMonitor = new BizMonitor();
    	//2016-01-13 16:41:47.662|82b1bd2eae194b188ee39db0216a1926|http-bio-8080-exec-9|INFO |performance-|Y|27|GET|/creditcms/applicateCredit/list?pageNo=1&pageSize=10&startTime=1450022400000&endTime=1452700799999&status=-2&_=1452672437128
    	Map<String,String> map = null;
		try {
			map = JSON.parseObject(msg, HashMap.class);
		}catch(JSONException e) {
			log.error("消息非JSON格式,直接返回,消息内容：{}",msg,e);
			return null;
		}
		bizMonitor.setSysname(Objects.toString(map.get("sysName"),""));
		String logStr = map.get("log");
		List<String> logArr = Splitter.on('|').splitToList(logStr);
		// 设置调用日期
		bizMonitor.setInvokeDate(logArr.get(0).substring(0, 10));
		bizMonitor.setInvokeTime(new DateTime(logArr.get(0).replace(" ", "T")).getMillis());
		
		// 设置UUID
		bizMonitor.setUuid(logArr.get(1));
		
		// 耗时,有可能打印的时间会有这种格式：2,345
				int costytime = Integer.valueOf(CharMatcher.is(',').replaceFrom(logArr.get(5), ""));
		// 判断SQL执行时间是否大于监控阀值,大于阀值监控,小于阀值忽略
    	if(costytime < Integer.valueOf(Objects.toString(map.get("threshold"), "0"))) {
    		return null;
    	}
    	bizMonitor.setExecutedTime(costytime);
    	
    	// 获取url
    	List<String> urls = Splitter.on("\n").splitToList(logArr.get(7));
    	bizMonitor.setMethod(logArr.get(6));
    	// 完整URL：url?params
    	String allUrl = urls.get(0);
    	if(logArr.get(6).equals("GET")) {
    		int indexOfWenHao = allUrl.indexOf('?');
    		bizMonitor.setBiz(allUrl.substring(0, indexOfWenHao));
    		bizMonitor.setParams(allUrl.substring(indexOfWenHao+1));
    	} else {
    		bizMonitor.setBiz(allUrl);
    		bizMonitor.setParams("");
    	}
    	return bizMonitor;
    }

}
